// need to be changed to https
package com.qilu.careprogram.sms.impl;

import com.qilu.careprogram.sms.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class SimpleSmsServiceImpl implements SmsService {

    @Value("${sms.aliyun.access-key-id}")
    private String accessKeyId;

    @Value("${sms.aliyun.access-key-secret}")
    private String accessKeySecret;

    @Value("${sms.aliyun.endpoint}")
    private String endpoint;

    @Value("${sms.aliyun.sign-name}")
    private String signName;

    @Value("${sms.aliyun.template-code}")
    private String templateCode;

    @Override
    public boolean sendVerificationCode(String phoneNumber, String code) {
        try {
            Map<String, String> params = buildParams(phoneNumber, code);
            String signature = generateSignature(params, accessKeySecret);
            params.put("Signature", signature);

            String queryString = buildQueryString(params);
            String url = "https://" + endpoint + "/?" + queryString;

            log.debug("发送短信验证码到 {}, URL: {}", phoneNumber, url);

            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();

                // 简单判断返回结果
                String responseStr = response.toString();
                log.debug("短信发送响应: {}", responseStr);
                return responseStr.contains("\"Code\":\"OK\"");
            }
            log.error("短信发送失败，HTTP状态码: {}", responseCode);
            return false;
        } catch (Exception e) {
            log.error("发送短信验证码异常: {}", e.getMessage(), e);
            return false;
        }
    }

    private Map<String, String> buildParams(String phoneNumber, String code) {
        Map<String, String> params = new HashMap<>();
        params.put("Format", "JSON");
        params.put("Version", "2017-05-25");
        params.put("SignatureMethod", "HMAC-SHA1");
        params.put("SignatureVersion", "1.0");
        params.put("SignatureNonce", UUID.randomUUID().toString());
        params.put("Timestamp", getFormattedTimestamp());
        params.put("AccessKeyId", accessKeyId);
        params.put("Action", "SendSms");
        params.put("RegionId", "cn-hangzhou");
        params.put("PhoneNumbers", phoneNumber);
        params.put("SignName", signName);
        params.put("TemplateCode", templateCode);
        params.put("TemplateParam", "{\"code\":\"" + code + "\"}");
        return params;
    }

    private String getFormattedTimestamp() {
        java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
        return df.format(new java.util.Date());
    }

    private String generateSignature(Map<String, String> params, String secret) throws Exception {
        // 排序参数
        java.util.TreeMap<String, String> sortedParams = new java.util.TreeMap<>(params);

        // 构建待签名的字符串
        StringBuilder queryString = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            queryString.append("&")
                    .append(percentEncode(entry.getKey()))
                    .append("=")
                    .append(percentEncode(entry.getValue()));
        }
        String stringToSign = "GET&%2F&" + percentEncode(queryString.substring(1));

        // 计算HMAC-SHA1签名
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HMAC-SHA1");
        mac.init(new javax.crypto.spec.SecretKeySpec((secret + "&").getBytes(StandardCharsets.UTF_8), "HMAC-SHA1"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));

        // Base64编码
        return java.util.Base64.getEncoder().encodeToString(signData);
    }

    private String percentEncode(String value) throws Exception {
        return URLEncoder.encode(value, StandardCharsets.UTF_8.name())
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~");
    }

    private String buildQueryString(Map<String, String> params) throws Exception {
        StringBuilder query = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            query.append(entry.getKey())
                    .append("=")
                    .append(percentEncode(entry.getValue()))
                    .append("&");
        }
        return query.substring(0, query.length() - 1);
    }
}